package com.x.uikit.page;

import android.app.Activity;
import android.content.Context;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.ref.WeakReference;

public class XPageManager {
    private static final SparseArray<WeakReference<XPageManager>> sPageManagers = new SparseArray<>();
    @NonNull
    private final XPageManagerConfig mConfig;

    private XPageEnvironment mEnvironment;
    @Nullable
    private XPageStack mPageStack;
    private XLifecycleListener mLifecycle;

    public XPageManager(@NonNull XPageManagerConfig config) {
        mConfig = config;
        Activity activity = config.activity;
        mEnvironment = new XPageEnvironment(activity);
        sPageManagers.put(activity.hashCode(), new WeakReference<>(this));
        if (config.rootPage != null) {
            checkAndCreatePageStack(config.rootPage);
        }
        mEnvironment.setFitsSystemWindows(config.fitSystemWindows);
        activity.setContentView(mEnvironment);
    }

    private void checkAndCreatePageStack(@NonNull XPage rootPage) {
        if (mPageStack == null) {
            Activity activity = mConfig.activity;
            mPageStack = new XPageStack(activity, rootPage);
            mEnvironment.getPageLayer().addView(mPageStack, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        }
    }

    public XLifecycleListener getLifecycle() {
        if (mLifecycle == null) {
            mLifecycle = new LifecycleImp();
        }
        return mLifecycle;
    }

    public Activity getActivity() {
        return mConfig.activity;
    }

    public static XPageManager of(Context context) {
        WeakReference<XPageManager> managerRef = sPageManagers.get(context.hashCode());
        if (managerRef != null && managerRef.get() != null) {
            return managerRef.get();
        }
        return null;
    }


    public boolean dispatchKeyEvent(KeyEvent keyEvent) {
        return mEnvironment.dispatchKeyEvent(keyEvent);
    }

    public boolean onBackPressed() {
        return mEnvironment.onBackPressed();

    }

    public void push(XPage page) {
        push(page, true);
    }

    public void push(XPage page, boolean animated) {
        IPageAnimator animator = null;
        if (animated) {
            animator = mConfig.pageAnimator;
        }
        push(page, animator);

    }

    public void push(XPage page, IPageAnimator animator) {
        if (mPageStack != null) {
            mPageStack.push(page, animator);
        } else {
            checkAndCreatePageStack(page);
        }
    }


    public void pop() {
        pop(true);
    }

    public void pop(boolean animated) {
        IPageAnimator animator = null;
        if (animated) {
            animator = mConfig.pageAnimator;
        }
        pop(animator);
    }

    public void pop(IPageAnimator animator) {
        if (mPageStack != null && mPageStack.canPop()) {
            mPageStack.pop(animator);
        } else {
            mConfig.activity.finish();
        }
    }

    public void finish(XPage page, IPageAnimator animator) {
        if (page == null || mPageStack == null) {
            return;
        }
        if (mPageStack.peek() == page) {
            pop(animator);
        } else {
            mPageStack.remove(page);
        }

    }

    public void finish(XPage page, boolean animated) {
        if (page == null) {
            return;
        }
        IPageAnimator animator = null;
        if (animated) {
            animator = mConfig.pageAnimator;
        }
        finish(page, animator);

    }

    private class LifecycleImp implements XLifecycleListener {

        @Override
        public void onCreate() {
        }

        @Override
        public void onStart() {
            if (mPageStack == null) {
                return;
            }
            XPage currentPage = mPageStack.peek();
            if (currentPage != null) {
                currentPage.getLifecycle().update(XLifecycle.State.START);
            }
        }

        @Override
        public void onResume() {
            if (mPageStack == null) {
                return;
            }
            XPage currentPage = mPageStack.peek();
            if (currentPage != null) {
                currentPage.getLifecycle().update(XLifecycle.State.RESUME);
            }
        }

        @Override
        public void onPause() {
            if (mPageStack == null) {
                return;
            }
            XPage currentPage = mPageStack.peek();
            if (currentPage != null) {
                currentPage.getLifecycle().update(XLifecycle.State.PAUSE);
            }
        }

        @Override
        public void onStop() {
            if (mPageStack == null) {
                return;
            }
            XPage currentPage = mPageStack.peek();
            if (currentPage != null) {
                currentPage.getLifecycle().update(XLifecycle.State.STOP);
            }
        }

        @Override
        public void onDestroy() {
            if (mPageStack == null) {
                return;
            }
            mPageStack.destroy();
        }
    }
}
